package com.qtu.order_service.service.impl;


import com.qtu.entity.*;
import com.qtu.order_service.mapper.*;
import com.qtu.order_service.openfeign.RedisFeignClient;

import com.qtu.order_service.service.CartService;
import com.qtu.util.CacheUtil;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author CaiYinWei
 * @create 2020-07-08 16:05
 */
@Service
public class CartServiceImpl implements CartService {
    //redis中购物车对应的key前缀
    private String REDIS_CART_KEY = "CART_KEY";

    //redis购物车商品项对应的key前缀
    private String REDIS_CART_ITEM_KEY = "CART_ITEM_KEY";
    @Autowired
    private RedisFeignClient redisFeignClient;

    @Autowired
    private BmGoodMapper bmGoodMapper;

    @Autowired
    private BmInordergoodslistMapper BmInordergoodslistMapper;

    @Autowired
    private BmInorderlistMapper bmInorderlistMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private BmMemberMapper bmMemberMapper;

    @Transactional
    @Override
    public String addToCart(String token, Integer Id, Integer num) {
        BmMember member = (BmMember)CacheUtil.linkedHashMapToObject(redisFeignClient.get(token), BmMember.class);
        String key = REDIS_CART_KEY+"_"+member.getId();
        CartItem cartItem = getCartItemByGoodsId(Id);

        Cart cart = (Cart)CacheUtil.linkedHashMapToObject(redisFeignClient.get(key), Cart.class);
        if (cart==null){
            cart=new Cart();
        }
        cart.addCartMap(cartItem,num);
        String result = redisFeignClient.setByTime(key, cart, 10000);
        return result;
    }

    @Override
    public CartItem getCartItemByGoodsId(Integer Id) {
        String key = REDIS_CART_ITEM_KEY+"_"+Id;
        CartItem cartItem = (CartItem) CacheUtil.linkedHashMapToObject(redisFeignClient.get(key), CartItem.class);
       //如果缓存中没有,从数据库查询
        if (cartItem==null){
            CartItem cartItem1 = bmGoodMapper.selectCartItemById(Id);
            String s = redisFeignClient.setByTime(key, cartItem1, 100);
            return cartItem1;
        }
        return cartItem;
    }

    @Override
    public Set<CartItem> getCartItemMap(String token){
        BmMember member = (BmMember)CacheUtil.linkedHashMapToObject(redisFeignClient.get(token), BmMember.class);

        String key =REDIS_CART_KEY+"_"+member.getId();

        System.out.println(redisFeignClient.get(key));

        Cart cart = (Cart)CacheUtil.linkedHashMapToObject(redisFeignClient.get(key), Cart.class);

        return cart.getList();
    }
    @Transactional
    @Override
    public String deleteItemFromCart(String token, Integer id){
        BmMember member = (BmMember)CacheUtil.linkedHashMapToObject(redisFeignClient.get(token), BmMember.class);

        String key =REDIS_CART_KEY+"_"+member.getId();
        Cart cart = (Cart)CacheUtil.linkedHashMapToObject(redisFeignClient.get(key), Cart.class);
        if (cart !=null){
            cart.deleteItem(id);
        }else {
            return "删除失败";
        }
        return "删除成功";
    }
    @Transactional
    @Override
    public String UpdateItemNumber(String token, Integer id, Integer num){
        BmMember member = (BmMember)CacheUtil.linkedHashMapToObject(redisFeignClient.get(token), BmMember.class);

        String key =REDIS_CART_KEY+"_"+member.getId();
        Cart cart = (Cart)CacheUtil.linkedHashMapToObject(redisFeignClient.get(key), Cart.class);

        if (cart !=null){
            cart.updateGoodsNum(id,num);
        }else {
            return "更新失败";
        }
        return null;
    }
    @Transactional
    @Override
    public SettlementBean settlement(String token,List<String> itemIds){
        BmMember member = (BmMember)CacheUtil.linkedHashMapToObject(redisFeignClient.get(token), BmMember.class);

        String key =REDIS_CART_KEY+"_"+member.getId();
        Cart cart = (Cart)CacheUtil.linkedHashMapToObject(redisFeignClient.get(key), Cart.class);
        BigDecimal totalPrice = new BigDecimal(0);
        BigDecimal totalDeliveryFee = new BigDecimal(0);
        SettlementBean settlementBean = new SettlementBean();
        Set<CartItem> list = cart.getList();
        if (cart !=null){

            for (String cid : itemIds){

                for (CartItem cartItem : list) {

                    if (Integer.parseInt(cid)==(cartItem.getId())){
                        BigDecimal price = cartItem.getPrice();
                        price = price.multiply(new BigDecimal(cartItem.getGoodsNum()));
                        //计算运费
                        if (member.getDeliveryFee() != null){
                            totalDeliveryFee = totalDeliveryFee.add(member.getDeliveryFee());
                        }

                        totalPrice = totalPrice.add(totalDeliveryFee);
                        totalPrice = totalPrice.add(price);
                    }

                }

            }

            settlementBean.setItemList(list);
            settlementBean.setTotalPrice(totalPrice);
            settlementBean.setTotalDeliveryFee(totalDeliveryFee);
        }

     return settlementBean;
    }
    @Transactional
    @Override
    public ConcurrentHashMap<Object, Object> commitOrder(String token, Set<CartItem> itemList, String mark, String addressId){
        ConcurrentHashMap<Object, Object> map = new ConcurrentHashMap<>();
        BmMember member = (BmMember)CacheUtil.linkedHashMapToObject(redisFeignClient.get(token), BmMember.class);

        String key =REDIS_CART_KEY+"_"+member.getId();
        String orderId = UUID.randomUUID().toString().replaceAll("-", "");
        BmInorderlist order = new BmInorderlist();
        order.setOrderId(orderId);
        //正常订单
        order.setOrderState(1);
        //订单步骤,未支付
        order.setOrderStep(1);
        order.setDeliveryAddId(addressId);
        order.setMark(mark);
        order.setSellerId(member.getId());
        order.setDeliveryFee(member.getDeliveryFee());
        redisFeignClient.setByTime("ORDER_"+orderId,order,30);

        for (CartItem cartItem : itemList) {
            //减少缓存中商品的库存数量
           String ItemKey=REDIS_CART_ITEM_KEY+"_"+ cartItem.getId();
           CartItem cartItem1 = (CartItem)CacheUtil.linkedHashMapToObject(redisFeignClient.get(ItemKey), CartItem.class);
            if (cartItem1==null){
                cartItem1= bmGoodMapper.selectCartItemById(cartItem.getId());
                redisFeignClient.setByTime(ItemKey,cartItem1,1000);

            }
            //解决超卖问题
            if(cartItem1.getStock()<=0){
                map.put("message","当前商品已售罄!");
                return map;
            }
            if (cartItem.getGoodsNum() >= cartItem1.getStock()){
                map.put("message","当前商品已售罄!");
                return map;
            }

            BmSpecification bmSpecification= new BmSpecification();

            Integer newStock= cartItem1.getStock()-cartItem.getGoodsNum();
            cartItem1.setStock(newStock);
            redisFeignClient.set(ItemKey,cartItem1);
            bmSpecification.setId(cartItem1.getId());
            bmSpecification.setStock(newStock);

            rabbitTemplate.convertAndSend("order.direct","order.commit",bmSpecification);

//                 rabbitTemplate.convertAndSend("order.direct.lazy", "lazy", orderId, message -> {
//                // 设置超时时间 1000*60*30ms
//                message.getMessageProperties().setExpiration("1000*60*30");
//                return message;
//                });
//
//            rabbitTemplate.convertAndSend("order.direct.lazy", "lazy", bmSpecification, message -> {
//                // 设置超时时间 1000*60*30ms
//                message.getMessageProperties().setExpiration("1000*60*30");
//                return message;
//            });


//            乐观锁
//            bmSpecificationMapper.updateById(bmSpecification);
            //生成订单商品
            BmInordergoodslist orderGoods = new BmInordergoodslist();
            //规格id
            orderGoods.setSpId(cartItem.getId());
            //商品id
            orderGoods.setGoodsId(cartItem.getGoodsId());
            //订单id
            orderGoods.setOrderId(orderId);
            //规格名称
            orderGoods.setSname(cartItem.getGoodsName());
            //商品名称
            orderGoods.setGoodsName(cartItem.getGoodsName());
            //商品图片
            orderGoods.setGoodsImg(cartItem.getGoodsImgUrl());
            //购买数量
            orderGoods.setBuyNum(cartItem.getGoodsNum());
            //商品价格
            orderGoods.setPrice(cartItem.getPrice());
//            redisFeignClient.setByTime("ORDERGOODS_"+cartItem.getId(),orderGoods,30);
            BmInordergoodslistMapper.insert(orderGoods);
        }
        //删除购物车里的所有商品
        Cart cart = (Cart)CacheUtil.linkedHashMapToObject(redisFeignClient.get(key), Cart.class);
        cart.deleteAll();
        redisFeignClient.set(key,cart);
//        rabbitTemplate.convertAndSend("order.direct","order.commit","aaaaaa");
        map.put("message","恭喜您，抢购成功！快快支付吧...");
        map.put("orderId",orderId);
        return map;
    }

    @Transactional
    @Override
    public ConcurrentHashMap<Object, Object> toPay(String token, String orderId, Integer payType, Integer money){
        BmMember member = (BmMember)CacheUtil.linkedHashMapToObject(redisFeignClient.get(token), BmMember.class);
        ConcurrentHashMap<Object, Object> map = new ConcurrentHashMap<>();
        BmInorderlist order = (BmInorderlist)CacheUtil.linkedHashMapToObject(redisFeignClient.get("ORDER_" + orderId), BmInorderlist.class);
//        CacheUtil.linkedHashMapToObject(redisFeignClient.get("ORDERGOODS_" + orderId), BmInorderlist.class);
        if (order==null){
            map.put("message","0");
            return map;
        }
        order.setOrderStep(2);
        order.setPayType(payType);
        order.setAmount(new BigDecimal(money));

        bmInorderlistMapper.insert(order);
        rabbitTemplate.convertAndSend(orderId);
        BmMember member1 = bmMemberMapper.selectById(member.getId());
        member1.setAmount(new BigDecimal(money));
        bmMemberMapper.updateById(member1);
        map.put("message","1");
        return map;
    }
}
